#include "orangepch.h"
#include "Application.h"

#include <iostream>
#define BIND_ON_EVENT(x) std::bind(&Application::x, this, std::placeholders::_1)

namespace Orange
{

    Application *Application::s_instance = nullptr;

    Application::Application(/* args */)
    {
        m_Window = Scope<Window>(Window::Create());
        m_Window->SetCallback(BIND_ON_EVENT(OnEvent));
        s_instance = this;

        m_ImGuiLayer = new ImGuiLayer();

        PushOverLayer(m_ImGuiLayer);

      
    };

    Application::~Application()
    {
        std::cout << "Application Destoryed" << std::endl;
    };

    void Application::Run()
    {
        while (m_running)
        {

         
            for (Layer *layer : m_LayerStack)
            {
                layer->OnUpdate();
            }

            m_ImGuiLayer->Begin();

            for (Layer *layer : m_LayerStack)
            {
                layer->OnImGuiRender();
            }

            m_ImGuiLayer->End();

            m_Window->OnUpdate();
        }
    };

    void Application::OnEvent(Event &event)
    {
        EventDispatch dispatch(event);

        dispatch.Dispatch<WindowCloseEvent>(BIND_ON_EVENT(OnWindowClose));

        ORANGE_CORE_TRACE("Event {0}", event.ToString());
    }

    bool Application::OnWindowClose(WindowCloseEvent &e)
    {
        m_running = false;
        return true;
    }

    void Application::PushLayer(Layer *layer)
    {
        m_LayerStack.PushLayer(layer);

        layer->OnAttach();
    };
    void Application::PushOverLayer(Layer *layer)
    {
        m_LayerStack.PushOverLayer(layer);

        layer->OnAttach();
    };
    void Application::PopLayer(Layer *layer)
    {

        layer->OnDetach();
        m_LayerStack.PopLayer(layer);
    };
    void Application::PopOverLayer(Layer *layer)
    {
        layer->OnDetach();
        m_LayerStack.PopLayer(layer);
    };
}